#ifndef _PALMVEIN_H_
#define _PALMVEIN_H_

#include "component.h"
#include "device.h"

/* 定义默认的指密卡掌静脉用户的数量 */
#if defined(DXTC_NO_MENU)
#define KOS_PARAM_USERS_QTY_PALMVEIN   50
#else
#ifndef KOS_PARAM_USERS_QTY_PALMVEIN
#define KOS_PARAM_USERS_QTY_PALMVEIN   20
#endif
#endif


/* 掌静脉动作类型 */
typedef enum
{
	PALMVEIN_ACTION_VERIFY_OK,				//验证成功
	PALMVEIN_ACTION_ADD_OK,					//添加成功
	PALMVEIN_ACTION_VERIFY_ERR,				//验证失败
	PALMVEIN_ACTION_NOPALMVEIN,				//未发现手掌
	PALMVEIN_ACTION_VERIFY_END,				//验证结束
	PALMVEIN_ACTION_ADD_ERR,				//添加失败
	PALMVEIN_ACTION_ADD_REPEAT,				//添加失败，掌静脉已存在
	PALMVEIN_ACTION_DEL_OK,					//删除成功
	PALMVEIN_ACTION_DEL_FAIL,				//删除失败
	PALMVEIN_ACTION_TOOUP,					//手掌放置太靠近上边沿，未能录入
	PALMVEIN_ACTION_TOODOWN,				//手掌放置太靠近下边沿，未能录入
	PALMVEIN_ACTION_TOOLEFT,				//手掌放置太靠近左边沿，未能录入
	PALMVEIN_ACTION_TOOLRIGHT,				//手掌放置太靠近右边沿，未能录入
	PALMVEIN_ACTION_NOT_MIDDLE,				//手掌未居中
	PALMVEIN_ACTION_FAR,					//手掌放置太远（高），未能录入
	PALMVEIN_ACTION_CLOSE,					//手掌放置太近（低），未能录入
	PALMVEIN_ACTION_DIRECTION_ERROR,		//录入掌静脉方向错误
	PALMVEIN_ACTION_MODULE_BREAKDOWN,		//掌静脉模组异常
	PALMVEIN_ACTION_ENTER_OTA_MODE,			//掌静脉模组进入ota模式
	PALMVEIN_ACTION_OTA_SENDING_FIRMWARE,	//掌静脉OTA正在发送升级包
	PALMVEIN_ACTION_OTA_READY,				//OTA准备好了
	PALMVEIN_ACTION_OTA_OK,					//OTA成功
	PALMVEIN_ACTION_OTA_ERR,				//OTA失败
	PALMVEIN_ACTION_ENC_SUCCESS,			//设置掌静脉加密秘钥序列成功
	PALMVEIN_ACTION_ENC_FAIL,				//设置掌静脉加密秘钥序列失败
	PALMVEIN_ACTION_ENCRYPTED,				//掌静脉加密密钥系列已经存在
	PALMVEIN_ACTION_TIME_OUT,				//超时
	PALMVEIN_ACTION_OTAING,					//掌静脉正在ota
	PALMVEIN_ACTION_MIDDLE_REMINDER,		//正视提醒
	PALMVEIN_ACTION_RIGHT_REMINDER,			//向右提醒
	PALMVEIN_ACTION_LEFT_REMINDER,			//向左提醒
	PALMVEIN_ACTION_DOWN_REMINDER,			//向下提醒
	PALMVEIN_ACTION_UP_REMINDER,			//向上提醒
	PALMVEIN_ACTION_POWER_ON,				//掌静脉上电
	PALMVEIN_ACTION_POWER_OFF,				//掌静脉掉电
	PALMVEIN_ACTION_GET_VERSION_OK,			//获取版本号成功
	PALMVEIN_ACTION_GET_VERSION_FAIL,		//获取版本号失败
	PALMVEIN_ACTION_OTA_PACK_SUCCESS,		//ota包成功
	PALMVEIN_ACTION_OTA_PACK_ERR,			//ota包失败
	PALMVEIN_ACTION_MAX,					//无效值
} PalmVeinActionType_enum_t;

/*掌静脉模式枚举*/
typedef enum
{
	PALMVEIN_MODULE_SLEEPED_MODE,	  		//掌静脉模组已经休眠断电 ：断电休眠模式
	PALMVEIN_MODULE_VERIFY_MODE, 			//掌静脉模组正在验证掌静脉 ：验证模式
	PALMVEIN_MODULE_ENROLL_MODE,	  		//掌静脉模组正在录入掌静脉:录入模式
	PALMVEIN_MODULE_DELETE_MODE,	  		//删除掌静脉模式
	PALMVEIN_MODULE_OTA_MODE,		  		//掌静脉模组正在升级掌静脉:升级模式
	PALMVEIN_MODULE_SLEEPING_MODE,	  		//掌静脉模组正在执行休眠动作 ：执行休眠模式
	PALMVEIN_MODULE_IDLE_MODE,		  //掌静脉模组空闲模式：上电状态受到结束指令转换到这个模式：空闲模式
	PALMVEIN_MODULE_SET_MODE,		  //掌静脉设置模式，用于掌静脉参数设置
	PALMVEIN_MAX_MODE,
} PalmVein_mode_enum_t;

typedef enum
{
	PALMVEIN_CTRL_ENROLL,			//录入
	PALMVEIN_CTRL_VERIFY,			//验证
	PALMVEIN_CTRL_VERIFY_DELETE,	//验证删除
	PALMVEIN_CTRL_DELETE,			//删除
	PALMVEIN_CTRL_ABORT,			//终止
	PALMVEIN_CTRL_SET_DEMO_MODE,	//设置演示模式		
	PALMVEIN_CTRL_SET_WORK_MODE,	//设置工作模式
	PALMVEIN_CTRL_SET_RELEASE_ENC,	//设置量产秘钥
    PALMVEIN_CTRL_GET_VERSION,      //获取版本号
	PALMVEIN_CTRL_START_OTA,		//启动OTA
	PALMVEIN_CTRL_POWER_OFF,		//断电
	PALMVEIN_CTRL_FACTORY_RESET,	//恢复出厂设置
	PALMVEIN_CTRL_OTA_POWER,		//OTA上电
	PALMVEIN_CTRL_OTA_PACK,			//OTA分包
	PALMVEIN_CTRL_MAX,
}PalmVein_ctrl_enum_t;

typedef enum
{
	PALMVEIN_USER_TYPE_ADMIN,	//管理员
	PALMVEIN_USER_TYPE_URGENT,	//胁迫
	PALMVEIN_USER_TYPE_NORMAL,	//普通
}PalmVein_Enroll_Type_enum_t;


/* PalmVein组件消息类型 */
typedef struct
{
	PalmVeinActionType_enum_t action; //动作
	uint8_t id;					  //用户id
} PalmVeinMsg_t;


#define PALMVEIN_MODEL_LEN                  6       //掌静脉模组型号长度
#define PALMVEIN_VERSION_LEN                10		//掌静脉版本号长度
#define PALMVEIN_SN_LEN                     20		//掌静脉sn长度
#define MAX_PALMVEIN_NUM   KOS_PARAM_USERS_QTY_PALMVEIN				//掌静脉最大数量

#pragma pack(1)
/* 掌静脉NV存储数据的结构体*/
typedef struct
{
	uint8_t palmveinReleaseFlag;			  //掌静脉经过产测，出厂状态标志 0:未产测    1：产测(已量产)
	uint8_t palmveinModel[PALMVEIN_MODEL_LEN];    //掌静脉型号
	uint8_t palmveinVesion[PALMVEIN_VERSION_LEN]; //掌静脉软件版本
	uint8_t palmveinSn[PALMVEIN_SN_LEN];		  //掌静脉模组sn
	uint16_t palmvein_user_id[MAX_PALMVEIN_NUM];
} NvPalmvein_stu_t;
#pragma pack()

#define PALMVEIN_NV_SIZE sizeof(NvPalmvein_stu_t)

#define PALMVEIN_MBOX_CTRL 			0
#define PALMVEIN_MBOX_OTA_START  	1
#define PALMVEIN_MBOX_OTA_PACK 		2
#define PALMVEIN_MBOX_OTA_TEST  	3




/* 正常操作接口 
  * @param ctrl : 控制操作
  * @param num  ： 用户id  ，录入或删除单个用户，填对应id
                    	  ，删除全部用户，填0xff
                    	  ，其他操作为空
  * @param type  ： 录入用户类型	0:管理员，1：胁迫，2：普通,	其他操作为空		
*/
#define PalmVein_Ctrl(ctrl,num,type)                                     \
({                                                                 	\
    uint8_t temp[4] = {PALMVEIN_MBOX_CTRL, ctrl,num,type};               \
    OSAL_MboxPost(COMP_PALMVEIN, 0, temp, sizeof(temp)); 	            \
})    


/* 获取版本号 */
#define PalmVein_GetVersion(ver)                                    \
({    																\
    (OSAL_NvReadGlobal(COMP_PALMVEIN,                          		\
                       0,                   						\
                       OSAL_OFFSET(NvPalmvein_stu_t, palmveinVesion), 		\
                       ver, 9) != ERROR) ? SUCCESS : ERROR; 		\
})

/* 获取model 型号 */
#define PalmVein_GetModel(model)                               	\
({                                                          	\
    (OSAL_NvReadGlobal(COMP_PALMVEIN,                          	\
                       0,                   					\
                       OSAL_OFFSET(NvPalmvein_stu_t, palmveinModel), 	\
                       model, 5) != ERROR) ? SUCCESS : ERROR; 	\
})

/* OTA启动接口 
  * @param mtu : 分包大小
  * @param len : 升级包总大小
  * @param md5  ： md5值
*/
#define PalmVein_OTA_Start(mtu,len,md5)                                 \
({                                                                 	\
    uint8_t temp[2+6+32] = {0};               \
	temp[0] = PALMVEIN_MBOX_OTA_START; \
	temp[1] = PALMVEIN_CTRL_START_OTA; \
	memcpy(temp+2, &mtu,2);                                          \
	memcpy(temp+4, &len,4);                                          \
	memcpy(temp+8, md5,32);										\
	printf("temp %d %d size %d \r\n",temp[2],temp[3],sizeof(temp));				\
    OSAL_MboxPost(COMP_PALMVEIN, 0, temp, sizeof(temp)); 	         \
})  

/* OTA分包接口
  * @param data : 升级分包内容
  * @param len  ： 包长
  * 
  * @note : malloc的长度 = 数据内容长度 + temp0 + temp1 +len(2 byte)
*/
#define PalmVein_OTA_Pack(data,len)                                 \
({                                                                 	\
    uint8_t *temp = (uint8_t *)OSAL_Malloc(len + 5);                \
	temp[0] = PALMVEIN_MBOX_OTA_PACK;								\
	temp[1] = PALMVEIN_CTRL_OTA_PACK;								\
	memcpy(&temp[2], &len,2);											\
	memcpy(&temp[4], data, len);									\
    OSAL_MboxPost(COMP_PALMVEIN, 0, temp, len+5); 	        \
    OSAL_Free(temp);                                                \
})  

/* OTA启动接口 
  * @param mtu : 分包大小
  * @param len : 升级包总大小
  * @param md5  ： md5值
*/
#define PalmVein_OTA_Start_Test()                                 \
({                                                                 	\
    uint8_t temp[2] = {PALMVEIN_MBOX_OTA_TEST,PALMVEIN_CTRL_START_OTA};               \
    OSAL_MboxPost(COMP_PALMVEIN, 0, temp, sizeof(temp)); 	         \
})  

#endif
